from fastapi import APIRouter, Depends, HTTPException, status, Query, BackgroundTasks
from fastapi.responses import StreamingResponse
from sqlalchemy.orm import Session
from typing import List, Optional, Dict
from datetime import datetime
import uuid
import logging
import asyncio
import json
from pydantic import BaseModel

logger = logging.getLogger(__name__)

from app.core.database import get_db
from app.core.config import settings
from app.core.security import get_current_active_user
from app.models.user import User
from app.models.chat import ChatSession, ChatMessage
from app.schemas.chat import (
    ChatSession as ChatSessionSchema,
    ChatMessage as ChatMessageSchema,
    ChatSessionCreate,
    ChatMessageCreate
)
from app.services.dify_service import dify_service

router = APIRouter()

# 任务状态管理
class MessageTask(BaseModel):
    task_id: str
    session_id: int
    user_id: int
    content: str
    status: str = "pending"  # pending, processing, completed, failed
    progress: float = 0.0
    message: Optional[ChatMessageSchema] = None
    error: Optional[str] = None
    created_at: datetime = datetime.utcnow()
    updated_at: datetime = datetime.utcnow()

# 内存中存储任务状态
message_tasks: Dict[str, MessageTask] = {}

# 异步处理消息任务
async def process_message_task(
    task_id: str,
    session_id: int,
    user_id: int,
    content: str,
    db: Session
):
    try:
        # 更新任务状态为处理中
        message_tasks[task_id].status = "processing"
        message_tasks[task_id].progress = 0.1
        message_tasks[task_id].updated_at = datetime.utcnow()
        
        # 获取会话
        session = db.query(ChatSession).filter(ChatSession.id == session_id).first()
        if not session:
            message_tasks[task_id].status = "failed"
            message_tasks[task_id].error = "会话不存在"
            message_tasks[task_id].updated_at = datetime.utcnow()
            return
        
        # 更新进度
        message_tasks[task_id].progress = 0.3
        message_tasks[task_id].updated_at = datetime.utcnow()
        
        # 调用Dify API获取回复
        start_time = datetime.utcnow()
        
        # 记录调用前的信息
        logger.info(f"准备调用Dify API: user_id={user_id}, session_id={session.session_id}, dify_conversation_id={session.dify_conversation_id or '新会话'}")
        
        # 根据Postman示例调整请求参数
        dify_response = await dify_service.send_message(
            message=content,
            user_id=str(user_id),
            conversation_id=session.dify_conversation_id,
            files=[]  # 根据Postman示例添加空的files参数
        )
        end_time = datetime.utcnow()
        response_time = (end_time - start_time).total_seconds()
        
        # 更新进度
        message_tasks[task_id].progress = 0.7
        message_tasks[task_id].updated_at = datetime.utcnow()
        
        # 记录调用结果
        logger.info(f"Dify API调用结果: success={dify_response['success']}, response_time={response_time}秒")
        
        if dify_response["success"]:
            # 解析Dify响应
            dify_data = dify_response["data"]
            ai_content = dify_data.get("answer", "抱歉，我无法回答这个问题。")
            
            # 记录Dify返回的关键信息
            logger.info(f"Dify返回信息: message_id={dify_data.get('message_id')}, conversation_id={dify_data.get('conversation_id')}, answer长度={len(ai_content)}")
            
            # 确保conversation_id存在且有效，然后再更新数据库
            if dify_data.get("conversation_id"):
                if not session.dify_conversation_id:
                    logger.info(f"更新会话的dify_conversation_id: {dify_data['conversation_id']}")
                    session.dify_conversation_id = dify_data["conversation_id"]
                elif session.dify_conversation_id != dify_data["conversation_id"]:
                    logger.warning(f"Dify返回的conversation_id与数据库中不一致: 数据库={session.dify_conversation_id}, Dify返回={dify_data['conversation_id']}")
                    # 使用最新的conversation_id
                    logger.info(f"更新为最新的conversation_id: {dify_data['conversation_id']}")
                    session.dify_conversation_id = dify_data["conversation_id"]
            
            # 创建AI回复消息，使用Dify返回的message_id
            ai_message = ChatMessage(
                session_id=session.id,
                message_id=dify_data.get("message_id", str(uuid.uuid4())),  # 优先使用Dify返回的message_id
                role="assistant",
                content=ai_content,
                content_type="text",
                model=dify_data.get("model", "dify-ai"),
                tokens=dify_data.get("metadata", {}).get("usage", {}).get("total_tokens", 0),
                response_time=response_time,
                meta_data=dify_data.get("metadata", {})  # 注意这里使用meta_data而不是metadata
            )
            
            db.add(ai_message)
            session.message_count += 1
            session.total_tokens += ai_message.tokens or 0
            
            db.commit()
            db.refresh(ai_message)
            
            # 更新任务状态为完成
            message_tasks[task_id].status = "completed"
            message_tasks[task_id].progress = 1.0
            message_tasks[task_id].message = ChatMessageSchema.from_orm(ai_message)
            message_tasks[task_id].updated_at = datetime.utcnow()
        else:
            # Dify API调用失败，返回错误消息
            error_detail = dify_response.get("message", "未知错误")
            error_response = dify_response.get("response_text", "")
            
            # 记录详细的错误信息
            logger.error(f"Dify API调用失败: {error_detail}")
            if error_response:
                logger.error(f"错误响应内容: {error_response[:500]}...")
                
            error_message = ChatMessage(
                session_id=session.id,
                message_id=str(uuid.uuid4()),
                role="assistant",
                content=f"抱歉，AI服务暂时不可用：{error_detail}",
                content_type="text",
                model="error",
                response_time=response_time,
                meta_data={"error": dify_response.get("error", ""), "exception": dify_response.get("exception", "")}
            )
            
            db.add(error_message)
            session.message_count += 1
            
            db.commit()
            db.refresh(error_message)
            
            # 更新任务状态为失败
            message_tasks[task_id].status = "failed"
            message_tasks[task_id].error = error_detail
            message_tasks[task_id].message = ChatMessageSchema.from_orm(error_message)
            message_tasks[task_id].updated_at = datetime.utcnow()
    except Exception as e:
        logger.exception(f"处理消息任务时发生异常: {str(e)}")
        # 更新任务状态为失败
        if task_id in message_tasks:
            message_tasks[task_id].status = "failed"
            message_tasks[task_id].error = str(e)
            message_tasks[task_id].updated_at = datetime.utcnow()

@router.get("/sessions", response_model=List[ChatSessionSchema], summary="获取聊天会话列表")
async def get_chat_sessions(
    skip: int = Query(0, ge=0, description="跳过记录数"),
    limit: int = Query(20, ge=1, le=100, description="返回记录数"),
    status: Optional[str] = Query(None, description="会话状态"),
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """
    获取当前用户的聊天会话列表
    """
    query = db.query(ChatSession).filter(ChatSession.user_id == current_user.id)
    
    if status:
        query = query.filter(ChatSession.status == status)
    
    sessions = query.order_by(ChatSession.updated_at.desc()).offset(skip).limit(limit).all()
    
    return [ChatSessionSchema.from_orm(session) for session in sessions]

@router.post("/sessions", response_model=ChatSessionSchema, summary="创建聊天会话")
async def create_chat_session(
    session_data: ChatSessionCreate,
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """
    创建新的聊天会话
    """
    # 创建会话
    session = ChatSession(
        session_id=str(uuid.uuid4()),
        user_id=current_user.id,
        title=session_data.title or "新对话",
        status="active"
    )
    
    db.add(session)
    db.commit()
    db.refresh(session)
    
    return ChatSessionSchema.from_orm(session)

@router.get("/sessions/{session_id}", response_model=ChatSessionSchema, summary="获取聊天会话详情")
async def get_chat_session(
    session_id: str,
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """
    获取指定聊天会话的详细信息
    """
    session = db.query(ChatSession).filter(
        ChatSession.session_id == session_id,
        ChatSession.user_id == current_user.id
    ).first()
    
    if not session:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="聊天会话不存在"
        )
    
    return ChatSessionSchema.from_orm(session)

@router.get("/sessions/{session_id}/messages", response_model=List[ChatMessageSchema], summary="获取聊天消息")
async def get_chat_messages(
    session_id: str,
    skip: int = Query(0, ge=0, description="跳过记录数"),
    limit: int = Query(50, ge=1, le=200, description="返回记录数"),
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """
    获取指定会话的聊天消息
    """
    # 验证会话所有权
    session = db.query(ChatSession).filter(
        ChatSession.session_id == session_id,
        ChatSession.user_id == current_user.id
    ).first()
    
    if not session:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="聊天会话不存在"
        )
    
    # 获取消息
    messages = db.query(ChatMessage).filter(
        ChatMessage.session_id == session.id
    ).order_by(ChatMessage.created_at.asc()).offset(skip).limit(limit).all()
    
    return [ChatMessageSchema.from_orm(message) for message in messages]

@router.post("/sessions/{session_id}/messages", summary="发送聊天消息")
async def send_chat_message(
    session_id: str,
    message_data: ChatMessageCreate,
    background_tasks: BackgroundTasks,
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """
    向指定会话发送消息，返回任务ID
    """
    # 验证会话所有权
    session = db.query(ChatSession).filter(
        ChatSession.session_id == session_id,
        ChatSession.user_id == current_user.id
    ).first()
    
    if not session:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="聊天会话不存在"
        )
    
    # 创建用户消息
    user_message = ChatMessage(
        session_id=session.id,
        message_id=str(uuid.uuid4()),
        role="user",
        content=message_data.content,
        content_type=message_data.content_type or "text"
    )
    
    db.add(user_message)
    db.commit()
    db.refresh(user_message)
    
    # 更新会话信息
    session.message_count += 1
    session.last_message_at = datetime.utcnow()
    if not session.title or session.title == "新对话":
        # 使用消息内容的前20个字符作为标题
        session.title = message_data.content[:20] + ("..." if len(message_data.content) > 20 else "")
    
    db.commit()
    
    # 创建任务ID
    task_id = str(uuid.uuid4())
    
    # 创建任务状态
    message_tasks[task_id] = MessageTask(
        task_id=task_id,
        session_id=session.id,
        user_id=current_user.id,
        content=message_data.content
    )
    
    # 在后台处理消息
    background_tasks.add_task(
        process_message_task,
        task_id=task_id,
        session_id=session.id,
        user_id=current_user.id,
        content=message_data.content,
        db=db
    )
    
    # 返回任务ID和用户消息
    return {
        "task_id": task_id,
        "user_message": ChatMessageSchema.from_orm(user_message),
        "status": "pending"
    }

@router.get("/tasks/{task_id}", summary="获取任务状态")
async def get_task_status(
    task_id: str,
    current_user: User = Depends(get_current_active_user)
):
    """
    获取指定任务的状态
    """
    if task_id not in message_tasks:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="任务不存在"
        )
    
    task = message_tasks[task_id]
    
    # 验证任务所有权
    if task.user_id != current_user.id:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="无权访问此任务"
        )
    
    # 返回任务状态
    return {
        "task_id": task.task_id,
        "status": task.status,
        "progress": task.progress,
        "message": task.message,
        "error": task.error,
        "created_at": task.created_at,
        "updated_at": task.updated_at
    }

@router.post("/sessions/{session_id}/messages/stream", summary="发送流式聊天消息")
async def send_chat_message_stream(
    session_id: str,
    message_data: ChatMessageCreate,
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """
    向指定会话发送消息并返回流式响应
    """
    # 验证会话所有权
    session = db.query(ChatSession).filter(
        ChatSession.session_id == session_id,
        ChatSession.user_id == current_user.id
    ).first()
    
    if not session:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="聊天会话不存在"
        )
    
    # 创建用户消息
    user_message = ChatMessage(
        session_id=session.id,
        message_id=str(uuid.uuid4()),
        role="user",
        content=message_data.content,
        content_type=message_data.content_type or "text"
    )
    
    db.add(user_message)
    db.commit()
    db.refresh(user_message)
    
    # 更新会话信息
    session.message_count += 1
    session.last_message_at = datetime.utcnow()
    if not session.title or session.title == "新对话":
        session.title = message_data.content[:20] + ("..." if len(message_data.content) > 20 else "")
    
    db.commit()
    
    async def generate_stream():
        """生成流式响应数据"""
        # 累积消息内容和元数据，确保即使 message_end 事件丢失也能保存
        accumulated_content = ""
        last_message_id = None
        last_conversation_id = None
        last_model = "dify-ai"
        last_metadata = {}
        events_received = []
        message_end_received = False
        
        try:
            # 创建一个自定义的JSON编码器来处理datetime对象
            class DateTimeEncoder(json.JSONEncoder):
                def default(self, obj):
                    if isinstance(obj, datetime):
                        return obj.isoformat()
                    return super().default(obj)
            
            logger.info(f"🚀 开始流式响应: session_id={session.id}, user_id={current_user.id}")
            
            # 发送开始事件 - 确保所有数据都能正确序列化
            user_message_dict = ChatMessageSchema.from_orm(user_message).dict()
            # 手动处理datetime字段
            if 'created_at' in user_message_dict and isinstance(user_message_dict['created_at'], datetime):
                user_message_dict['created_at'] = user_message_dict['created_at'].isoformat()
            if 'updated_at' in user_message_dict and isinstance(user_message_dict['updated_at'], datetime):
                user_message_dict['updated_at'] = user_message_dict['updated_at'].isoformat()
                
            yield f"data: {json.dumps({'event': 'start', 'data': {'user_message': user_message_dict}}, ensure_ascii=False)}\n\n"
            
            # 从请求中提取errorinfo
            errorinfo = message_data.inputs.get('errorinfo', '') if message_data.inputs else ''
            
            # 调用 Dify 流式 API
            stream_count = 0
            async for stream_data in dify_service.send_message_stream(
                message=message_data.content,
                user_id=str(current_user.id),
                conversation_id=session.dify_conversation_id,
                files=[],
                errorinfo=errorinfo
            ):
                stream_count += 1
                event_type = stream_data.get('event', 'unknown')
                events_received.append(event_type)
                
                logger.info(f"📨 收到流式事件 #{stream_count}: {event_type}")
                
                # 累积消息内容和元数据
                if event_type == 'message':
                    data = stream_data.get('data', {})
                    if 'answer' in data:
                        accumulated_content += data['answer']
                        logger.debug(f"   累积内容长度: {len(accumulated_content)}")
                    
                    # 更新元数据
                    if 'message_id' in data:
                        last_message_id = data['message_id']
                    if 'conversation_id' in data:
                        last_conversation_id = data['conversation_id']
                    if 'model' in data:
                        last_model = data['model']
                    if 'metadata' in data:
                        last_metadata = data['metadata']
                
                # 转发流式数据
                yield f"data: {json.dumps(stream_data, cls=DateTimeEncoder, ensure_ascii=False)}\n\n"
                
                # 如果是消息结束事件，保存 AI 回复到数据库
                if event_type == 'message_end':
                    message_end_received = True
                    logger.info("🏁 检测到 message_end 事件，开始保存消息...")
                    
                    message_data_obj = stream_data.get('data', {})
                    
                    # 使用 message_end 中的数据，如果没有则使用累积的数据
                    final_content = message_data_obj.get('answer', accumulated_content)
                    final_message_id = message_data_obj.get('message_id', last_message_id or str(uuid.uuid4()))
                    final_conversation_id = message_data_obj.get('conversation_id', last_conversation_id)
                    final_model = message_data_obj.get('model', last_model)
                    final_metadata = message_data_obj.get('metadata', last_metadata)
                    
                    logger.info(f"💾 准备保存AI消息:")
                    logger.info(f"   - 内容长度: {len(final_content)}")
                    logger.info(f"   - message_id: {final_message_id}")
                    logger.info(f"   - conversation_id: {final_conversation_id}")
                    logger.info(f"   - model: {final_model}")
                    
                    if final_content:
                        try:
                            # 创建新的数据库会话以确保事务正确性
                            from app.core.database import SessionLocal
                            with SessionLocal() as new_db:
                                # 重新获取会话对象
                                current_session = new_db.query(ChatSession).filter(
                                    ChatSession.id == session.id
                                ).first()
                                
                                if current_session:
                                    # 创建 AI 回复消息
                                    ai_message = ChatMessage(
                                        session_id=current_session.id,
                                        message_id=final_message_id,
                                        role="assistant",
                                        content=final_content,
                                        content_type="text",
                                        model=final_model,
                                        tokens=final_metadata.get('usage', {}).get('total_tokens', 0),
                                        meta_data=final_metadata
                                    )
                                    
                                    new_db.add(ai_message)
                                    current_session.message_count += 1
                                    current_session.total_tokens += ai_message.tokens or 0
                                    
                                    # 更新会话的 dify_conversation_id
                                    if final_conversation_id:
                                        current_session.dify_conversation_id = final_conversation_id
                                    
                                    new_db.commit()
                                    new_db.refresh(ai_message)
                                    
                                    logger.info(f"✅ AI消息已成功保存到数据库: ID={ai_message.id}, message_id={ai_message.message_id}")
                                    
                                    # 发送保存完成事件 - 确保datetime字段正确序列化
                                    ai_message_dict = ChatMessageSchema.from_orm(ai_message).dict()
                                    # 手动处理datetime字段
                                    if 'created_at' in ai_message_dict and isinstance(ai_message_dict['created_at'], datetime):
                                        ai_message_dict['created_at'] = ai_message_dict['created_at'].isoformat()
                                    if 'updated_at' in ai_message_dict and isinstance(ai_message_dict['updated_at'], datetime):
                                        ai_message_dict['updated_at'] = ai_message_dict['updated_at'].isoformat()
                                    
                                    yield f"data: {json.dumps({'event': 'saved', 'data': {'ai_message': ai_message_dict}}, ensure_ascii=False)}\n\n"
                                else:
                                    logger.error(f"❌ 无法找到会话: session_id={session.id}")
                                    yield f"data: {json.dumps({'event': 'error', 'data': {'message': '会话不存在，无法保存消息'}}, ensure_ascii=False)}\n\n"
                        except Exception as save_error:
                            logger.exception(f"❌ 保存AI消息到数据库失败: {str(save_error)}")
                            yield f"data: {json.dumps({'event': 'save_error', 'data': {'message': f'保存消息失败: {str(save_error)}'}}, ensure_ascii=False)}\n\n"
                    else:
                        logger.warning("⚠️  message_end 事件中没有有效的 answer 内容")
                
                # 如果是错误事件，也保存错误消息
                elif stream_data.get('event') == 'error':
                    error_data = stream_data.get('data', {})
                    try:
                        # 创建新的数据库会话以确保事务正确性
                        from app.core.database import SessionLocal
                        with SessionLocal() as new_db:
                            # 重新获取会话对象
                            current_session = new_db.query(ChatSession).filter(
                                ChatSession.id == session.id
                            ).first()
                            
                            if current_session:
                                error_message = ChatMessage(
                                    session_id=current_session.id,
                                    message_id=str(uuid.uuid4()),
                                    role="assistant",
                                    content=f"抱歉，AI服务暂时不可用：{error_data.get('message', '未知错误')}",
                                    content_type="text",
                                    model="error",
                                    meta_data={"error": error_data.get('error', ''), "stream_error": True}
                                )
                                
                                new_db.add(error_message)
                                current_session.message_count += 1
                                new_db.commit()
                                new_db.refresh(error_message)
                                
                                # 发送错误保存完成事件 - 确保datetime字段正确序列化
                                error_message_dict = ChatMessageSchema.from_orm(error_message).dict()
                                # 手动处理datetime字段
                                if 'created_at' in error_message_dict and isinstance(error_message_dict['created_at'], datetime):
                                    error_message_dict['created_at'] = error_message_dict['created_at'].isoformat()
                                if 'updated_at' in error_message_dict and isinstance(error_message_dict['updated_at'], datetime):
                                    error_message_dict['updated_at'] = error_message_dict['updated_at'].isoformat()
                                
                                yield f"data: {json.dumps({'event': 'error_saved', 'data': {'error_message': error_message_dict}}, ensure_ascii=False)}\n\n"
                                logger.info(f"错误消息已成功保存到数据库: message_id={error_message.message_id}")
                            else:
                                logger.error(f"无法找到会话: session_id={session.id}")
                    except Exception as save_error:
                        logger.exception(f"保存错误消息到数据库失败: {str(save_error)}")
                        yield f"data: {json.dumps({'event': 'save_error', 'data': {'message': f'保存错误消息失败: {str(save_error)}'}}, ensure_ascii=False)}\n\n"
            
            # 检查是否需要备用保存机制
            if not message_end_received and accumulated_content:
                logger.warning("⚠️  未收到 message_end 事件，但有累积内容，启用备用保存机制")
                
                try:
                    # 使用累积内容保存消息
                    from app.core.database import SessionLocal
                    with SessionLocal() as new_db:
                        current_session = new_db.query(ChatSession).filter(
                            ChatSession.id == session.id
                        ).first()
                        
                        if current_session:
                            backup_ai_message = ChatMessage(
                                session_id=current_session.id,
                                message_id=last_message_id or str(uuid.uuid4()),
                                role="assistant",
                                content=accumulated_content,
                                content_type="text",
                                model=last_model,
                                tokens=last_metadata.get('usage', {}).get('total_tokens', 0),
                                meta_data={**last_metadata, "backup_save": True, "reason": "message_end_missing"}
                            )
                            
                            new_db.add(backup_ai_message)
                            current_session.message_count += 1
                            current_session.total_tokens += backup_ai_message.tokens or 0
                            
                            if last_conversation_id:
                                current_session.dify_conversation_id = last_conversation_id
                            
                            new_db.commit()
                            new_db.refresh(backup_ai_message)
                            
                            logger.info(f"🔄 备用保存成功: ID={backup_ai_message.id}, 内容长度={len(accumulated_content)}")
                            
                            # 发送备用保存完成事件
                            backup_message_dict = ChatMessageSchema.from_orm(backup_ai_message).dict()
                            if 'created_at' in backup_message_dict and isinstance(backup_message_dict['created_at'], datetime):
                                backup_message_dict['created_at'] = backup_message_dict['created_at'].isoformat()
                            if 'updated_at' in backup_message_dict and isinstance(backup_message_dict['updated_at'], datetime):
                                backup_message_dict['updated_at'] = backup_message_dict['updated_at'].isoformat()
                            
                            yield f"data: {json.dumps({'event': 'saved', 'data': {'ai_message': backup_message_dict, 'backup_save': True}}, ensure_ascii=False)}\n\n"
                        else:
                            logger.error(f"❌ 备用保存失败: 无法找到会话 session_id={session.id}")
                            
                except Exception as backup_save_error:
                    logger.exception(f"❌ 备用保存机制失败: {str(backup_save_error)}")
                    yield f"data: {json.dumps({'event': 'save_error', 'data': {'message': f'备用保存失败: {str(backup_save_error)}'}}, ensure_ascii=False)}\n\n"
            
            # 记录流式响应统计
            logger.info(f"📊 流式响应完成统计:")
            logger.info(f"   - 总事件数: {stream_count}")
            logger.info(f"   - 事件类型: {list(set(events_received))}")
            logger.info(f"   - 累积内容长度: {len(accumulated_content)}")
            logger.info(f"   - message_end已接收: {message_end_received}")
            
            # 发送完成事件
            yield f"data: {json.dumps({'event': 'complete', 'data': {'message': '流式响应完成', 'stats': {'events': len(events_received), 'content_length': len(accumulated_content), 'message_end_received': message_end_received}}}, ensure_ascii=False)}\n\n"
            
        except Exception as e:
            logger.exception(f"❌ 流式响应生成异常: {str(e)}")
            error_type = type(e).__name__
            error_detail = str(e)
            logger.error(f"异常类型: {error_type}, 详细信息: {error_detail}")
            
            # 在异常处理中也尝试保存累积的内容
            if accumulated_content:
                logger.info(f"🔄 异常处理中尝试保存累积的消息内容: 长度={len(accumulated_content)}")
                try:
                    from app.core.database import SessionLocal
                    with SessionLocal() as emergency_db:
                        current_session = emergency_db.query(ChatSession).filter(
                            ChatSession.id == session.id
                        ).first()
                        
                        if current_session:
                            emergency_ai_message = ChatMessage(
                                session_id=current_session.id,
                                message_id=last_message_id or str(uuid.uuid4()),
                                role="assistant",
                                content=accumulated_content,
                                content_type="text",
                                model=last_model,
                                tokens=last_metadata.get('usage', {}).get('total_tokens', 0),
                                meta_data={
                                    **last_metadata, 
                                    "emergency_save": True, 
                                    "reason": "exception_recovery",
                                    "exception_type": error_type,
                                    "exception_detail": error_detail[:500]  # 限制长度
                                }
                            )
                            
                            emergency_db.add(emergency_ai_message)
                            current_session.message_count += 1
                            current_session.total_tokens += emergency_ai_message.tokens or 0
                            
                            if last_conversation_id:
                                current_session.dify_conversation_id = last_conversation_id
                            
                            emergency_db.commit()
                            emergency_db.refresh(emergency_ai_message)
                            
                            logger.info(f"🚑 紧急保存成功: ID={emergency_ai_message.id}, 内容长度={len(accumulated_content)}")
                            
                            # 发送紧急保存完成事件
                            emergency_message_dict = ChatMessageSchema.from_orm(emergency_ai_message).dict()
                            if 'created_at' in emergency_message_dict and isinstance(emergency_message_dict['created_at'], datetime):
                                emergency_message_dict['created_at'] = emergency_message_dict['created_at'].isoformat()
                            if 'updated_at' in emergency_message_dict and isinstance(emergency_message_dict['updated_at'], datetime):
                                emergency_message_dict['updated_at'] = emergency_message_dict['updated_at'].isoformat()
                            
                            yield f"data: {json.dumps({'event': 'saved', 'data': {'ai_message': emergency_message_dict, 'emergency_save': True}}, ensure_ascii=False)}\n\n"
                        else:
                            logger.error(f"❌ 紧急保存失败: 无法找到会话 session_id={session.id}")
                            
                except Exception as emergency_save_error:
                    logger.exception(f"❌ 紧急保存机制失败: {str(emergency_save_error)}")
            
            # 检查是否是 Dify API 连接问题
            if "ConnectionError" in error_type or "Timeout" in error_type or "Connection" in error_detail:
                error_message = "无法连接到 Dify API 服务，请检查网络连接或 API 配置"
            elif "Unauthorized" in error_detail or "401" in error_detail:
                error_message = "Dify API 认证失败，请检查 API Key 是否正确"
            elif "Not Found" in error_detail or "404" in error_detail:
                error_message = "Dify API 资源不存在，请检查 API URL 是否正确"
            else:
                error_message = "流式响应生成失败"
            
            logger.error(f"向客户端返回错误: {error_message}")
            
            # 如果没有累积内容，保存错误消息
            if not accumulated_content:
                try:
                    from app.core.database import SessionLocal
                    with SessionLocal() as new_db:
                        current_session = new_db.query(ChatSession).filter(
                            ChatSession.id == session.id
                        ).first()
                        
                        if current_session:
                            exception_message = ChatMessage(
                                session_id=current_session.id,
                                message_id=str(uuid.uuid4()),
                                role="assistant",
                                content=f"抱歉，AI服务暂时不可用：{error_message}",
                                content_type="text",
                                model="error",
                                meta_data={"error": error_detail, "error_type": error_type, "exception": True}
                            )
                            
                            new_db.add(exception_message)
                            current_session.message_count += 1
                            new_db.commit()
                            new_db.refresh(exception_message)
                            
                            logger.info(f"异常消息已保存到数据库: message_id={exception_message.message_id}")
                except Exception as save_exception:
                    logger.exception(f"保存异常消息到数据库失败: {str(save_exception)}")
            
            # 发送错误事件，不使用DateTimeEncoder避免进一步的序列化问题
            yield f"data: {json.dumps({'event': 'error', 'data': {'error': error_detail, 'message': f'抱歉，AI服务暂时不可用：{error_message}', 'error_type': error_type}}, ensure_ascii=False)}\n\n"
    
    return StreamingResponse(
        generate_stream(),
        media_type="text/event-stream",
        headers={
            "Cache-Control": "no-cache",
            "Connection": "keep-alive",
            "Access-Control-Allow-Origin": "*",
            "Access-Control-Allow-Headers": "*",
        }
    )

@router.put("/sessions/{session_id}", response_model=ChatSessionSchema, summary="更新聊天会话")
async def update_chat_session(
    session_id: str,
    title: Optional[str] = None,
    status: Optional[str] = None,
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """
    更新聊天会话信息
    """
    # 验证会话所有权
    session = db.query(ChatSession).filter(
        ChatSession.session_id == session_id,
        ChatSession.user_id == current_user.id
    ).first()
    
    if not session:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="聊天会话不存在"
        )
    
    # 更新字段
    if title is not None:
        session.title = title
    if status is not None:
        session.status = status
    
    db.commit()
    db.refresh(session)
    
    return ChatSessionSchema.from_orm(session)

@router.delete("/sessions/{session_id}", summary="删除聊天会话")
async def delete_chat_session(
    session_id: str,
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """
    删除聊天会话及其所有消息
    """
    # 验证会话所有权
    session = db.query(ChatSession).filter(
        ChatSession.session_id == session_id,
        ChatSession.user_id == current_user.id
    ).first()
    
    if not session:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="聊天会话不存在"
        )
    
    # 删除会话（级联删除消息）
    db.delete(session)
    db.commit()
    
    return {"message": "聊天会话删除成功"}

@router.post("/messages/{message_id}/rating", summary="评价消息")
async def rate_message(
    message_id: str,
    rating: int = Query(..., ge=1, le=5, description="评分(1-5)"),
    feedback: Optional[str] = Query(None, description="反馈内容"),
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """
    对AI回复消息进行评价
    """
    # 查找消息
    message = db.query(ChatMessage).join(ChatSession).filter(
        ChatMessage.message_id == message_id,
        ChatSession.user_id == current_user.id,
        ChatMessage.role == "assistant"
    ).first()
    
    if not message:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="消息不存在或无权限评价"
        )
    
    # 更新评价
    message.rating = rating
    message.feedback = feedback
    
    db.commit()
    
    return {"message": "评价提交成功"}

@router.get("/test-auth", summary="测试用户认证")
async def test_auth(
    current_user: User = Depends(get_current_active_user)
):
    """
    测试用户认证状态
    """
    return {
        "status": "success",
        "message": "用户认证成功",
        "user": {
            "id": current_user.id,
            "username": current_user.username,
            "email": current_user.email,
            "is_active": current_user.is_active,
            "is_superuser": current_user.is_superuser,
            "roles": [role.name for role in current_user.roles] if current_user.roles else []
        }
    }

@router.get("/test-dify", summary="测试Dify API连接")
async def test_dify_connection(
    current_user: User = Depends(get_current_active_user)
):
    """
    测试Dify API连接状态
    """
    try:
        # 记录测试开始
        logger.info(f"开始测试Dify API连接: API_KEY={settings.DIFY_API_KEY[:4]}***{settings.DIFY_API_KEY[-4:] if len(settings.DIFY_API_KEY) > 8 else ''}, BASE_URL={settings.DIFY_BASE_URL}")
        
        # 发送测试消息
        test_response = await dify_service.send_message(
            message="Hello, this is a test message.",
            user_id=str(current_user.id)
        )
        
        # 记录测试结果
        if test_response["success"]:
            logger.info(f"Dify API测试成功: {test_response.get('message', '')}")
        else:
            logger.error(f"Dify API测试失败: {test_response.get('message', '')}")
        
        return {
            "status": "success" if test_response["success"] else "failed",
            "message": test_response.get("message", ""),
            "data": test_response.get("data", {}) if test_response["success"] else test_response.get("error", ""),
            "config": {
                "api_key_prefix": f"{settings.DIFY_API_KEY[:4]}***",
                "api_key_suffix": f"***{settings.DIFY_API_KEY[-4:] if len(settings.DIFY_API_KEY) > 8 else ''}",
                "base_url": settings.DIFY_BASE_URL
            }
        }
    except Exception as e:
        logger.exception(f"测试Dify API连接时发生异常: {str(e)}")
        return {
            "status": "error",
            "message": f"测试连接时发生错误: {str(e)}"
        }

@router.get("/stats/summary", summary="获取聊天统计")
async def get_chat_stats(
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """
    获取当前用户的聊天统计信息
    """
    # 会话统计
    total_sessions = db.query(ChatSession).filter(ChatSession.user_id == current_user.id).count()
    active_sessions = db.query(ChatSession).filter(
        ChatSession.user_id == current_user.id,
        ChatSession.status == "active"
    ).count()
    
    # 消息统计
    total_messages = db.query(ChatMessage).join(ChatSession).filter(
        ChatSession.user_id == current_user.id
    ).count()
    
    # 今日消息
    today = datetime.utcnow().date()
    today_messages = db.query(ChatMessage).join(ChatSession).filter(
        ChatSession.user_id == current_user.id,
        ChatMessage.created_at >= datetime.combine(today, datetime.min.time())
    ).count()
    
    # 平均满意度
    avg_rating = db.query(ChatMessage).join(ChatSession).filter(
        ChatSession.user_id == current_user.id,
        ChatMessage.rating.isnot(None)
    ).with_entities(ChatMessage.rating).all()
    
    average_rating = sum(r[0] for r in avg_rating) / len(avg_rating) if avg_rating else 0
    
    return {
        "total_sessions": total_sessions,
        "active_sessions": active_sessions,
        "total_messages": total_messages,
        "today_messages": today_messages,
        "average_rating": round(average_rating, 2)
    }